import logging
from datetime import datetime
from fastapi import Request, Response
from typing import Optional
from pathlib import Path
import json
import traceback


# 日志配置类
class LogConfig:
    def __init__(self):
        self.log_dir = Path(__file__).parent.parent / "logs"
        self.log_dir.mkdir(exist_ok=True)

        file_handler = logging.FileHandler(
            self.log_dir / "app.log",
            encoding='utf-8'  # 明确指定UTF-8编码
        )
        error_handler = logging.FileHandler(
            self.log_dir / "error.log",
            encoding='utf-8'  # 明确指定UTF-8编码
        )

        # 基础配置
        logging.basicConfig(
            level=logging.INFO,
            format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
            handlers=[
                file_handler,
                logging.StreamHandler()
            ]
        )

        # 错误日志单独配置
        error_handler.setLevel(logging.ERROR)
        error_handler.setFormatter(
            logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
        )
        logging.getLogger('error').addHandler(error_handler)


# FastAPI 日志中间件
async def log_middleware(request: Request, call_next):
    logger = logging.getLogger("api")
    start_time = datetime.now()

    # 请求日志
    request_info = {
        "method": request.method,
        "url": str(request.url),
        "headers": dict(request.headers),
        "client": request.client.host if request.client else None
    }
    logger.info(f"Request: {json.dumps(request_info, indent=2, ensure_ascii=False)}")

    try:
        response = await call_next(request)
    except Exception as e:
        # 异常日志
        error_logger = logging.getLogger("error")
        error_logger.error(
            f"Exception: {str(e)}\n"
            f"Traceback: {traceback.format_exc()}\n"
            f"Request: {request_info}"
        )
        raise

    # 响应日志
    process_time = (datetime.now() - start_time).total_seconds() * 1000
    response_info = {
        "status_code": response.status_code,
        "process_time": f"{process_time:.2f}ms"
    }
    logger.info(f"Response: {json.dumps(response_info, indent=2, ensure_ascii=False)}")

    return response


# 业务日志工具
def log_message(
        action: str,
        details: Optional[dict] = None,
        level: str = "info"
):
    """通用业务日志记录"""
    logger = getattr(logging, level)
    log_data = {
        "action": action,
        "timestamp": datetime.now().isoformat(),
        "details": details or {}
    }
    logger(json.dumps(log_data, ensure_ascii=False))
